{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "## 01 kNN 基础"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### kNN 基础概念\n",
    "\n",
    "见PPT"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 实现我们自己的 kNN"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 创建简单测试用例"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "raw_data_X = [[3.393533211, 2.331273381],\n",
    "              [3.110073483, 1.781539638],\n",
    "              [1.343808831, 3.368360954],\n",
    "              [3.582294042, 4.679179110],\n",
    "              [2.280362439, 2.866990263],\n",
    "              [7.423436942, 4.696522875],\n",
    "              [5.745051997, 3.533989803],\n",
    "              [9.172168622, 2.511101045],\n",
    "              [7.792783481, 3.424088941],\n",
    "              [7.939820817, 0.791637231]\n",
    "             ]\n",
    "raw_data_y = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1]   # 0 表示良性肿瘤， 1表示恶性肿瘤"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = np.array(raw_data_X)\n",
    "y_train = np.array(raw_data_y)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[3.39353321, 2.33127338],\n",
       "       [3.11007348, 1.78153964],\n",
       "       [1.34380883, 3.36836095],\n",
       "       [3.58229404, 4.67917911],\n",
       "       [2.28036244, 2.86699026],\n",
       "       [7.42343694, 4.69652288],\n",
       "       [5.745052  , 3.5339898 ],\n",
       "       [9.17216862, 2.51110105],\n",
       "       [7.79278348, 3.42408894],\n",
       "       [7.93982082, 0.79163723]])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([0, 0, 0, 0, 0, 1, 1, 1, 1, 1])"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y_train"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x8d83908>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(X_train[y_train==0,0], X_train[y_train==0,1], color='g')\n",
    "plt.scatter(X_train[y_train==1,0], X_train[y_train==1,1], color='r')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "预测："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x8e2e080>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "x = np.array([8.093607318, 3.365731514])\n",
    "\n",
    "plt.scatter(X_train[y_train==0,0], X_train[y_train==0,1], color='g')\n",
    "plt.scatter(X_train[y_train==1,0], X_train[y_train==1,1], color='r')\n",
    "plt.scatter(x[0], x[1], color='b')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### kNN的过程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from math import sqrt\n",
    "# 两个点的距离称之为欧拉距离，  如果不在同一条直线， 可以理解为求三角形的斜边\n",
    "distances = []\n",
    "for x_train in X_train:\n",
    "    d = sqrt(np.sum((x_train - x)**2))\n",
    "    distances.append(d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4.812566907609877,\n",
       " 5.229270827235305,\n",
       " 6.749798999160064,\n",
       " 4.6986266144110695,\n",
       " 5.83460014556857,\n",
       " 1.4900114024329525,\n",
       " 2.354574897431513,\n",
       " 1.3761132675144652,\n",
       " 0.3064319992975,\n",
       " 2.5786840957478887]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "distances"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 和上面的效果一样，  只是写法不同\n",
    "distances = [sqrt(np.sum((x_train - x)**2))\n",
    "             for x_train in X_train]       "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[4.812566907609877,\n",
       " 5.229270827235305,\n",
       " 6.749798999160064,\n",
       " 4.6986266144110695,\n",
       " 5.83460014556857,\n",
       " 1.4900114024329525,\n",
       " 2.354574897431513,\n",
       " 1.3761132675144652,\n",
       " 0.3064319992975,\n",
       " 2.5786840957478887]"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "distances"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([8, 7, 5, 6, 9, 3, 0, 1, 4, 2], dtype=int64)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.argsort(distances)   #升序排序，  返回对应的下标"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "nearest = np.argsort(distances)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "k = 6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 找到前k和最近的点的坐标对应的y值\n",
    "topK_y = [y_train[neighbor] for neighbor in nearest[:k]]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[1, 1, 1, 1, 1, 0]"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "topK_y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "from collections import Counter\n",
    "votes = Counter(topK_y)   #对数组中出现的元素进行统计"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Counter({0: 1, 1: 5})"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "votes"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(1, 5)]"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "votes.most_common(1)   # 找出票数最多的1个元素"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "predict_y = votes.most_common(1)[0][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "predict_y"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
